package datamining.strategy;


import static de.parsemis.miner.environment.Debug.VVVERBOSE;
import static de.parsemis.miner.environment.Debug.out;

import java.util.Collection;
import java.util.Iterator;

import datamining.algorithms.Algorithm;
import datamining.miner.chain.Extender;
import datamining.miner.chain.SearchLatticeNode;
import datamining.miner.enviroment.Debug;
import datamining.miner.enviroment.LocalEnvironment;
import datamining.miner.general.Fragment;
import datamining.sequence.Sequence;

/** 
 * @author xujinghu, E-mail: jinghuxu@nudt.edu.cn
 * @date 2012-11-14 涓嬪崍2:51:51 
 * @version 
 */
public class RecursiveStrategy implements Strategy {

	protected Extender extender;

	protected Collection<Fragment> ret;

	@Override
	public Collection<Fragment> search(Algorithm algo) {

		 ret = LocalEnvironment.env().getReturnSet();
		extender = algo.getExtender(0);
		final long begin_time = System.currentTimeMillis();
		
		for (final Iterator<SearchLatticeNode> it = algo.initialNodes(); it.hasNext();) {
			final SearchLatticeNode code = it.next();
			final long time = System.currentTimeMillis();
			if (Debug.VERBOSE) {
				System.out.print("doing seed " + code + " ...");
			}

			search(code);
			it.remove();

			if (Debug.VERBOSE) {
				System.out.println("\tdone (" + (System.currentTimeMillis() - time)
						+ " ms)");
			}
		}
		
		if (Debug.VERBOSE) {
			System.out.println("\n####################################################\n" +
					"search all done in ("
					+ (System.currentTimeMillis() - begin_time)
					+ " ms)\n #################################################");
		}

		return ret;
	}

	private void search(final SearchLatticeNode node) {

		final Collection<SearchLatticeNode> tmp = extender.getChildren(node);

		for (final SearchLatticeNode child : tmp) {
			if (VVVERBOSE) {
				out.println("\n----------------LEVEL[" + child.getLevel() + "]-------------------");
				out.println("doing " + child);
			}

			search(child);

		}

/*		if (VVERBOSE) {
			out.println("node " + node + " done. Store: " + node.store()
					+ " children " + tmp.size() + " freq "
					+ ((Frequented) node).frequency());
		}*/

		if (node.store()) {
			node.store(ret);
		} else {
			node.release();
		}

		node.finalizeIt();
	}
	
	
}
